'use client'

import { z } from 'zod'
import { useFieldArray, useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { Button } from '@/components/ui/button'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { type DictItem } from '../data/schema'
import { useRouter } from '@tanstack/react-router'
import { useDictAdd, useDictUpdate } from '@/api/dicts'
import { toast } from 'sonner'
import { IconPlus, IconTrash } from '@tabler/icons-react'

const formSchema = z.object({
  name: z.string().min(1, 'Name is required.'),
  value: z.array(z.object({
    name: z.string().min(1, 'Label is required.'),
    value: z.string().min(1, 'Value is required.'),
  })).min(1, 'At least one value is required.'),
})

type DictForm = z.infer<typeof formSchema>

interface Props {
  currentRow?: DictItem
  open: boolean
  onOpenChange: (open: boolean) => void
}

export function DictsActionDialog({ currentRow, open, onOpenChange }: Props) {
  const router = useRouter()
  const isEdit = !!currentRow
  const form = useForm<DictForm>({
    resolver: zodResolver(formSchema),
    defaultValues: isEdit
      ? {
        ...currentRow,
      }
      : {
        name: '',
        value: [{ name: '', value: '' }],
      },
  })

  const { fields, append, remove } = useFieldArray({
    control: form.control,
    name: "value",
  });

  const dictAdd = useDictAdd()
  const dictUpdate = useDictUpdate()

  const onSubmit = (values: DictForm) => {
    if (currentRow) {
      dictUpdate.mutate({ ...currentRow, ...values }, {
        onSuccess: () => {
          onOpenChange(false)
          form.reset()
          router.invalidate();
          toast.success('Dictionary Updated')
        }
      })
    } else {
      dictAdd.mutate(values, {
        onSuccess: () => {
          onOpenChange(false)
          form.reset()
          router.invalidate();
          toast.success('Dictionary Saved')
        },
      })
    }
  }

  return (
    <Dialog
      open={open}
      onOpenChange={(state) => {
        form.reset()
        onOpenChange(state)
      }}
    >
      <DialogContent className='sm:max-w-lg'>
        <DialogHeader className='text-left'>
          <DialogTitle>{isEdit ? 'Edit Dictionary' : 'Add New Dictionary'}</DialogTitle>
          <DialogDescription>
            {isEdit ? 'Update the dictionary here. ' : 'Create new dictionary here. '}
            Click save when you're done.
          </DialogDescription>
        </DialogHeader>
        <div className='-mr-4 h-[26.25rem] w-full overflow-y-auto py-1 pr-4'>
          <Form {...form}>
            <form
              id='dict-form'
              onSubmit={form.handleSubmit(onSubmit)}
              className='space-y-4 p-0.5'
            >
              <FormField
                control={form.control}
                name='name'
                render={({ field }) => (
                  <FormItem className='grid grid-cols-6 items-center space-y-0 gap-x-4 gap-y-1'>
                    <FormLabel className='col-span-2 text-right'>
                      Name
                    </FormLabel>
                    <FormControl>
                      <Input
                        placeholder='e.g., gender'
                        className='col-span-4'
                        {...field}
                      />
                    </FormControl>
                    <FormMessage className='col-span-4 col-start-3' />
                  </FormItem>
                )}
              />
              <div>
                {fields.map((field, index) => (
                  <div key={field.id} className="grid grid-cols-6 items-center space-y-0 gap-x-4 gap-y-1 mb-2">
                    <FormLabel className='col-span-2 text-right'>
                      Value {index + 1}
                    </FormLabel>
                    <div className="col-span-4 grid grid-cols-2 gap-2">
                      <FormField
                        control={form.control}
                        name={`value.${index}.name`}
                        render={({ field }) => (
                          <FormItem>
                            <FormControl>
                              <Input {...field} placeholder="Label" />
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )}
                      />
                      <FormField
                        control={form.control}
                        name={`value.${index}.value`}
                        render={({ field }) => (
                          <FormItem>
                            <FormControl>
                              <Input {...field} placeholder="Value" />
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )}
                      />
                    </div>
                    {fields.length > 1 && (
                      <div className="col-span-1 col-start-6 flex justify-end">
                        <Button type="button" variant="ghost" size="sm" onClick={() => remove(index)}>
                          <IconTrash size={16} />
                        </Button>
                      </div>
                    )}
                  </div>
                ))}
                <div className="flex justify-end">
                  <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    onClick={() => append({ name: "", value: "" })}
                  >
                    <IconPlus size={16} className="mr-1" /> Add Value
                  </Button>
                </div>
              </div>
            </form>
          </Form>
        </div>
        <DialogFooter>
          <Button type='submit' form='dict-form'>
            Save changes
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
